package main

import (
	"database/sql"
	"flag"
	"fmt"
	"log"
	"os"

	"rdiot-demo/internal/shared/config"
	"rdiot-demo/migrations"

	_ "github.com/lib/pq"
)

func main() {
	var (
		configPath = flag.String("config", "configs/config.yaml", "配置文件路径")
		action     = flag.String("action", "migrate", "操作类型: migrate|status|reset|version")
		help       = flag.Bool("help", false, "显示帮助信息")
	)
	flag.Parse()

	if *help {
		printHelp()
		return
	}

	// 加载配置
	cfg, err := config.LoadConfig(*configPath)
	if err != nil {
		log.Fatalf("加载配置失败: %v", err)
	}

	// 连接数据库
	db, err := connectDatabase(cfg)
	if err != nil {
		log.Fatalf("连接数据库失败: %v", err)
	}
	defer db.Close()

	// 创建迁移器
	migrator := migrations.NewMigrator(db)

	// 执行对应操作
	switch *action {
	case "migrate":
		if err := migrate(migrator); err != nil {
			log.Fatalf("执行迁移失败: %v", err)
		}
	case "status":
		if err := showStatus(migrator); err != nil {
			log.Fatalf("获取状态失败: %v", err)
		}
	case "version":
		if err := showVersion(migrator); err != nil {
			log.Fatalf("获取版本失败: %v", err)
		}
	case "reset":
		if err := resetDatabase(migrator); err != nil {
			log.Fatalf("重置数据库失败: %v", err)
		}
	default:
		fmt.Printf("未知操作: %s\n", *action)
		printHelp()
		os.Exit(1)
	}
}

func printHelp() {
	fmt.Println(`数据库迁移工具

用法:
  go run cmd/tools/migrate/main.go [选项]

选项:
  -config string    配置文件路径 (默认: "configs/config.yaml")
  -action string    操作类型 (默认: "migrate")
  -help            显示帮助信息

操作类型:
  migrate    执行数据库迁移（默认）
  status     显示迁移状态
  version    显示当前数据库版本
  reset      重置数据库（危险操作，仅用于开发环境）

示例:
  # 执行迁移
  go run cmd/tools/migrate/main.go

  # 查看迁移状态
  go run cmd/tools/migrate/main.go -action=status

  # 查看当前版本
  go run cmd/tools/migrate/main.go -action=version

  # 重置数据库（开发环境）
  go run cmd/tools/migrate/main.go -action=reset`)
}

func connectDatabase(cfg *config.Config) (*sql.DB, error) {
	// 构建数据库连接字符串
	dsn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=%s",
		cfg.Database.Host,
		cfg.Database.Port,
		cfg.Database.User,
		cfg.Database.Password,
		cfg.Database.DBName,
		cfg.Database.SSLMode,
	)

	db, err := sql.Open("postgres", dsn)
	if err != nil {
		return nil, fmt.Errorf("打开数据库连接失败: %w", err)
	}

	// 测试连接
	if err := db.Ping(); err != nil {
		return nil, fmt.Errorf("数据库连接测试失败: %w", err)
	}

	fmt.Printf("成功连接到数据库: %s:%d/%s\n", cfg.Database.Host, cfg.Database.Port, cfg.Database.DBName)
	return db, nil
}

func migrate(migrator *migrations.Migrator) error {
	fmt.Println("开始执行数据库迁移...")

	if err := migrator.Migrate(); err != nil {
		return err
	}

	fmt.Println("数据库迁移完成！")
	return showVersion(migrator)
}

func showStatus(migrator *migrations.Migrator) error {
	fmt.Println("迁移状态:")
	fmt.Println("========================================")

	statuses, err := migrator.GetMigrationStatus()
	if err != nil {
		return err
	}

	if len(statuses) == 0 {
		fmt.Println("没有找到迁移文件")
		return nil
	}

	fmt.Printf("%-8s %-10s %s\n", "版本", "状态", "名称")
	fmt.Println("----------------------------------------")

	for _, status := range statuses {
		statusStr := "未应用"
		if status.Applied {
			statusStr = "已应用"
		}
		fmt.Printf("%-8d %-10s %s\n", status.Version, statusStr, status.Name)
	}

	return nil
}

func showVersion(migrator *migrations.Migrator) error {
	version, err := migrator.GetCurrentVersion()
	if err != nil {
		return err
	}

	if version == 0 {
		fmt.Println("当前数据库版本: 未迁移")
	} else {
		fmt.Printf("当前数据库版本: %d\n", version)
	}

	return nil
}

func resetDatabase(migrator *migrations.Migrator) error {
	fmt.Print("警告：此操作将删除所有数据！确认要重置数据库吗？(y/N): ")

	var response string
	fmt.Scanln(&response)

	if response != "y" && response != "Y" && response != "yes" {
		fmt.Println("操作已取消")
		return nil
	}

	fmt.Println("正在重置数据库...")

	if err := migrator.Reset(); err != nil {
		return err
	}

	fmt.Println("数据库重置完成")
	return nil
}
